/*
 *  Copyright (C) 1993  Robert Davis
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of Version 2, or any later version, of 
 *  the GNU General Public License as published by the Free Software 
 *  Foundation.
 */

static char RCSId[]="$Id: FunctionPane.m,v 1.5 1993/05/30 10:01:53 davis Exp $";

#import <appkit/Application.h>
#import <appkit/Cell.h>
#import <appkit/View.h>

#import "DataOptionsPanel.h"
#import "EditMatrix.h"
#import "FunctionObject.h"
#import "FunctionPane.h"
#import "Status.h"
#import "SubObjectCategory.h"

#define	STYLE		0
#define	STYLE_LINE	1
#define	STYLE_POINTS	2

@interface FunctionPane (Private)
- (int)_findMultStyleType:(int)type ofMatrix:(Matrix *)aMatrix;
- _setStyleType:(unsigned int)type to:(int)style;
@end


@implementation FunctionPane

- init
{
    [super init];

    [NXApp loadNibSection: "FunctionPane.nib"
		    owner: self
		withNames: NO
		 fromZone: [self zone]];

    return self;
}



- (BOOL)updateStatus:aStatus doc:aDoc
{
    /*  
     *  aDoc should be the controlling object that we can query for 
     *  the current function, function matrix, etc.
     */
    FunctionObject *f = [aDoc function];
    EditMatrix	*fm = [aDoc functionsMatrix];
    int		style;
    BOOL	styleRight;
    BOOL	isMult = [fm multipleCellsSelected];

    [super updateStatus:aStatus doc:aDoc];

    if (isMult) {		/* Multiple functions selected */

	[styleMatrix selectCellWithTag:
		[self _findMultStyleType:STYLE ofMatrix:fm]];
	[pointsStyleMatrix selectCellWithTag:
		[self _findMultStyleType:STYLE_POINTS ofMatrix:fm]];
	[lineStyleMatrix selectCellWithTag:
		[self _findMultStyleType:STYLE_LINE ofMatrix:fm]];

    } else if (f) {		/* Single function selected */

	[styleMatrix selectCellWithTag: [f style]];
	[pointsStyleMatrix selectCellWithTag: [f pointsStyle]];
	[lineStyleMatrix selectCellWithTag: [f lineStyle]];

    } else if (!f) {		/* No selection */

	[styleMatrix selectCellWithTag: FUNCTION_NOSTYLE];
	[pointsStyleMatrix selectCellWithTag: POINTS_NOSTYLE];
	[lineStyleMatrix selectCellWithTag: LINE_NOSTYLE];

    }

    [styleMatrix setEnabled:isMult || f];

    if (isMult || f) {

        BOOL    isThreeD = [status isThreeD];

        [[styleMatrix findCellWithTag:FUNCTION_BOXES] setEnabled:!isThreeD];
        [[styleMatrix findCellWithTag:FUNCTION_BOXERRORBARS] setEnabled:
								!isThreeD];
        [[styleMatrix findCellWithTag:FUNCTION_STEPS] setEnabled:!isThreeD];

    }

    style = [styleMatrix selectedTag];
    styleRight = (isMult || f) &&
        ((style == FUNCTION_POINTS) || (style == FUNCTION_LINESPOINTS));
    [pointsStyleMatrix setEnabled:styleRight];
    [pointsStyleLabel setEnabled:styleRight];

    styleRight = (isMult || f) &&
        ((style == FUNCTION_LINES) || (style == FUNCTION_LINESPOINTS));
    [lineStyleMatrix setEnabled:styleRight];
    [lineStyleLabel setEnabled:styleRight];


    /* The boxes cell should also be disabled */

    [[[[styleMatrix superview] superview] cell] setEnabled:isMult || f];

    return YES;
}



- setFunctionStyle:sender
{
    [self _setStyleType:STYLE to:[sender selectedTag]];
    if ([self forceUpdateStatus:status doc:doc])
	[view display];
    return self;
}

  
  
- setFunctionPointsStyle:sender
{
    return [self _setStyleType:STYLE_POINTS to:[sender selectedTag]];
}



- setFunctionLineStyle:sender
{
    return [self _setStyleType:STYLE_LINE to:[sender selectedTag]];
}



// Shuts up the compiler about unused RCSId
- (const char *) rcsid
{
    return RCSId;
}


@end


@implementation FunctionPane (Private)

- (int)_findMultStyleType:(int)type ofMatrix:(Matrix *)aMatrix;
{
    Cell	*cell;
    int		i, style = FUNCTION_NOSTYLE;
    BOOL	gotStyle = NO;
    int		defaultStyle;

    switch (type) {
    case STYLE_LINE:	defaultStyle = POINTS_NOSTYLE; break;
    case STYLE_POINTS:	defaultStyle = LINE_NOSTYLE; break;
    default:		defaultStyle = FUNCTION_NOSTYLE; break;
    }

    for (i = [aMatrix cellCount] - 1; i >= 0; i--) {
	cell = [aMatrix cellAt:i:0];

	if ([cell isHighlighted])  {
	    int	cellstyle;
	    switch (type) {
	    case STYLE_LINE:
		cellstyle = [[cell subObject] lineStyle]; break;
	    case STYLE_POINTS:
		cellstyle = [[cell subObject] pointsStyle]; break;
	    default:
		cellstyle = [[cell subObject] style]; break;
	    }

	    if (gotStyle) {
		if (cellstyle != style)
		    return defaultStyle;
	    } else {
		style = cellstyle;
		gotStyle = YES;
	    }
	}
    }

    return style;
}




- _setStyleType:(unsigned int)type to:(int)style
{
    BOOL		didChange = NO;
    FunctionObject	*f = [doc function];

    if (f) {

	switch (type) {
	case STYLE:		[f setStyle: style]; break;
	case STYLE_LINE:	[f setLineStyle: style]; break;
	case STYLE_POINTS:	[f setPointsStyle: style]; break;
	}

	didChange = YES;

    } else {

	Cell		*cell;
	EditMatrix	*fm = [doc functionsMatrix];
	int		i;

	if ([fm multipleCellsSelected]) {
	    for (i = [fm cellCount] - 1 ; i >= 0 ; i--) {
		cell = [fm cellAt:i:0];
		if ([cell isHighlighted])  {

		    switch (type) {
		    case STYLE:
			[[cell subObject] setStyle: style]; break;
		    case STYLE_LINE:
			[[cell subObject] setLineStyle: style]; break;
		    case STYLE_POINTS:
			[[cell subObject] setPointsStyle: style]; break;
		    }

		    didChange = YES;
		}
	    }
	}

    }

    if (didChange) {
	[status reportSettingsChange:self];

	/* Setting style may affect other controls */
	[self forceUpdateStatus:status doc:doc];
    }

    return self;
}


@end
